[SLOF] [PATCH v3 6/7] tcgbios: Add test cases and test script to run them
Alexey Kardashevskiy
aik at ozlabs.ru
Sat Jul 10 00:07:18 AEST 2021
On 09/07/2021 22:07, Stefan Berger wrote:
> On 7/9/21 2:02 AM, Alexey Kardashevskiy wrote:
>
>>
>>
>> On 09/07/2021 12:53, Stefan Berger wrote:
>>> From: Stefan Berger <stefanb at linux.ibm.com>
>>>
>>> Add test cases for sha1, sha256, sha384, and sha512 and a test script
>>> to run the test cases.
>>>
>>> Signed-off-by: Stefan Berger <stefanb at linux.ibm.com>
>>> ---
>>> lib/libtpm/sha.c | 26 +++++++++++++++++++
>>> lib/libtpm/sha256.c | 25 +++++++++++++++++++
>>> lib/libtpm/sha512.c | 32 ++++++++++++++++++++++++
>>> lib/libtpm/sha_test.h | 58 +++++++++++++++++++++++++++++++++++++++++++
>>> lib/libtpm/test.sh | 29 ++++++++++++++++++++++
>>> 5 files changed, 170 insertions(+)
>>> create mode 100644 lib/libtpm/sha_test.h
>>> create mode 100755 lib/libtpm/test.sh
>>>
>>> diff --git a/lib/libtpm/sha.c b/lib/libtpm/sha.c
>>> index 43de658..6e8b19b 100644
>>> --- a/lib/libtpm/sha.c
>>> +++ b/lib/libtpm/sha.c
>>> @@ -203,3 +203,29 @@ void sha1(const uint8_t *data, uint32_t length,
>>> uint8_t *hash)
>>> sha1_do(&ctx, data, length);
>>> memcpy(hash, &ctx.h[0], 20);
>>> }
>>> +
>>> +#ifdef MAIN
>>> +
>>> +#include "sha_test.h"
>>> +
>>> +int main(void)
>>> +{
>>> + TESTVECTORS(data);
>>> + uint8_t hash[20];
>>> + char input[64];
>>> + int err = 0;
>>> + size_t i;
>>> +
>>> + for (i = 0; data[i]; i++)
>>> + err |= test_hash(sha1, hash, sizeof(hash),
>>> + data[i], strlen(data[i]),
>>> + SHA1);
>>> +
>>> + memset(input, 'a', sizeof(input));
>>> + for (i = 50; i < sizeof(input); i++)
>>
>>
>> Why 50?
>
>
> There's a critical point in the input size for sha1 at around 56 bytes.
> I mainly wanted to cover that.
This is fine but then it calls for a macro, something like
SHA1_CRIT_SIZE which you then use in sha.c and in the test. I never ever
wrote a single bit of sha so I really wish to have some clues here.
> https://github.com/aik/SLOF/blob/master/lib/libtpm/sha.c#L170
>
> The same is true for sha256 at 56 bytes:
>
> https://github.com/aik/SLOF/blob/master/lib/libtpm/sha256.c#L176
>
> For sha512/sha384 it is at 112 bytes:
>
> https://github.com/aik/SLOF/blob/master/lib/libtpm/sha512.c#L186
>
>
>>
>>
>>> + err |= test_hash(sha256, hash, sizeof(hash), input, i, SHA256);
>>> +
>>> + return err;
>>> +}
>>> +#endif
>>> diff --git a/lib/libtpm/sha512.c b/lib/libtpm/sha512.c
>>> index f9267ef..9e856ea 100644
>>> --- a/lib/libtpm/sha512.c
>>> +++ b/lib/libtpm/sha512.c
>>> @@ -247,3 +247,35 @@ void sha512(const uint8_t *data, uint32_t
>>> length, uint8_t *hash)
>>> sha512_do(&ctx, data, length);
>>> memcpy(hash, ctx.h, sizeof(ctx.h));
>>> }
>>> +
>>> +
>>> +#ifdef MAIN
>>> +
>>> +#include "sha_test.h"
>>> +
>>> +int main(void)
>>> +{
>>> + TESTVECTORS(data);
>>> + uint8_t hash[64];
>>> + char input[128];
>>> + int err = 0;
>>> + size_t i;
>>> +
>>> + for (i = 0; data[i]; i++) {
>>> + err |= test_hash(sha384, hash, 48,
>>
>> Uff. Why 2 separate tests for 48 and sizeof(hash) here but everywhere
>> else it is just sizeof(hash)?
>
> Ok, let me revise.
>
>
>>
>>
>>
>>> + data[i], strlen(data[i]),
>>> + SHA384);
>>> + err |= test_hash(sha512, hash, sizeof(hash),
>>> + data[i], strlen(data[i]),
>>> + SHA512);
>>> + }
>>> +
>>> + memset(input, 'a', sizeof(input));
>>> + for (i = 110; i < sizeof(input); i++) {
>>
>>
>> Why 100 and not 50? ;)
>
>
> See above.
>
>>
>>
>>> + err |= test_hash(sha384, hash, 48, input, i, SHA384);
>>> + err |= test_hash(sha512, hash, sizeof(hash), input, i, SHA512);
>>> + }
>>> +
>>> + return err;
>>> +}
>>> +#endif
>>> diff --git a/lib/libtpm/sha_test.h b/lib/libtpm/sha_test.h
>>> new file mode 100644
>>> index 0000000..e1358f9
>>> --- /dev/null
>>> +++ b/lib/libtpm/sha_test.h
>>> @@ -0,0 +1,58 @@
>>> +/*****************************************************************************
>>>
>>> + * Copyright (c) 2021 IBM Corporation
>>> + * All rights reserved.
>>> + * This program and the accompanying materials
>>> + * are made available under the terms of the BSD License
>>> + * which accompanies this distribution, and is available at
>>> + * http://www.opensource.org/licenses/bsd-license.php
>>> + *
>>> + * Contributors:
>>> + * IBM Corporation - initial implementation
>>> +
>>> *****************************************************************************/
>>>
>>> +
>>> +#ifndef SHA_TEST_H
>>> +#define SHA_TEST_H
>>> +
>>> +#include <stdio.h>
>>> +
>>> +/* to avoid compilation issues do not include openssl/sha.h */
>>> +unsigned char *SHA1(const unsigned char *, size_t, unsigned char *);
>>> +unsigned char *SHA256(const unsigned char *, size_t, unsigned char *);
>>> +unsigned char *SHA384(const unsigned char *, size_t, unsigned char *);
>>> +unsigned char *SHA512(const unsigned char *, size_t, unsigned char *);
>>> +
>>> +typedef void (*hashfunc)(const uint8_t *data, uint32_t length,
>>> uint8_t *hash);
>>> +typedef unsigned char *(*osslhashfunc)(const unsigned char *, size_t,
>>> + unsigned char *);
>>> +
>>> +#define TESTVECTORS(NAME) \
>>> +char *NAME[] = { \
>>> + "", \
>>> + "abc", \
>>> + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", \
>>> +
>>> "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
>>> \
>>> + NULL \
>>
>>
>> Use ARRAY_SIZE(NAME) and ditch this last NULL?
>
>
> Ok.
>
>
>>
>>
>>> +};
>>> +
>>> +static inline int
>>> +test_hash(hashfunc hf, uint8_t *hash, size_t hashlen,
>>> + const char *data, uint32_t length,
>>> + osslhashfunc osslhf)
>>> +{
>>> + unsigned char expected[hashlen];
>>> + int ret = 0;
>>> +
>>> + osslhf((const unsigned char *)data, length, expected);
>>> +
>>> + hf((uint8_t *)data, length, hash);
>>> + if (!memcmp(hash, expected, hashlen)) {
>>> + printf("PASS\n");
>>> + } else {
>>> + printf("FAIL data: %s\n", data);
>>> + ret = 1;
>>> + }
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +#endif /* SHA_TEST_H */
>>> diff --git a/lib/libtpm/test.sh b/lib/libtpm/test.sh
>>> new file mode 100755
>>> index 0000000..f375fbc
>>> --- /dev/null
>>> +++ b/lib/libtpm/test.sh
>>> @@ -0,0 +1,29 @@
>>> +#!/usr/bin/env bash
>>> +cd $(dirname "$0")
>>> +
>>> +function fail() {
>>> + echo "Test failed"
>>> + exit 1
>>
>> If we end up here, the produced binaries are not removed.
>>
>>
>>> +}
>>> +
>>> +CC=${HOSTCC:-gcc}
>>> +CFLAGS="-Wall -Wextra -Werror -I../../include -I../../slof
>>> -I../../lib/libc/include -DMAIN"
>>> +LDFLAGS="-lcrypto"
>>> +
>>> +echo "SHA-1 test:"
>>> +${CC} ${CFLAGS} sha.c -o sha-test ${LDFLAGS} || exit 1
>>
>>
>> This produces a little endian binary (as these days PPC64 is pretty
>> much always LE) but SLOF and libtpm are big endian and this is a
>> potential source of bugs, the test must somehow take this into account
>> imho. I am really not sure how to address this though :-/
>
>
> I ran it on an old big endian Fedora 28. Well, it works there.
ok, this will do, may be leave a note in the commit log. Thanks,
> The only
> other choice would be to add this as self-tests into SLOF and use
> hard-coded results for comparison.
>
>
>>
>>
>>
>>> +./sha-test || fail
>>> +rm -f sha-test
>>> +
>>> +echo "SHA-256 test:"
>>> +${CC} ${CFLAGS} sha256.c -o sha256-test ${LDFLAGS} || exit 1
>>> +./sha256-test || fail
>>> +rm -f sha256-test
>>> +
>>> +echo "SHA-384 & 512 test:"
>>> +${CC} ${CFLAGS} sha512.c -o sha512-test ${LDFLAGS} || exit 1
>>> +./sha512-test || fail
>>> +rm -f sha512-test
>>> +
>>> +echo "All tests passed"
>>> +exit 0
>>>
>>
--
Alexey
More information about the SLOF
mailing list