[SLOF] [PATCH v3 6/7] tcgbios: Add test cases and test script to run them
Stefan Berger
stefanb at linux.ibm.com
Fri Jul 9 22:07:50 AEST 2021
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.
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. 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
>>
>
More information about the SLOF
mailing list