The makefile build specifies -L. -lmbedx509 -lmbedcrypto flags first,
and only then object files referencing symbols from those libraries.
In this order the linker will not add the linked libraries to the
DT_NEEDED section because they are not referenced yet (at least that
happens for me on ubuntu 20.04 with the default gnu compiler tools).
By first specifying the object files and then the linked libraries, we
do end up with libmbedx509 and libmbedcrypto in the DT_NEEDED sections.
This way running dlopen(...) on libmedtls.so just works.
Note that the CMake build does this by default.
Signed-off-by: Harmen Stoppels <harmenstoppels@gmail.com>
At least twice, we added a classification flag but forgot to test it in the
relevant test functions. Add some protection so that this doesn't happen
again. In each classification category, put a macro xxx_FLAG_MASK_PLUS_ONE
at the end. In the corresponding test function, keep track of the flags that
are tested, and check that their mask is xxx_FLAG_MASK_PLUS_ONE - 1 which is
all the bits of the previous flags set.
Now, if we add a flag without testing it, the test
TEST_EQUAL( classification_flags_tested, xxx_FLAG_MASK_PLUS_ONE - 1 )
will fail. It will also fail if we make the set of flag numbers
non-consecutive, which is ok.
This reveals that three algorithm flags had been added but not tested (in
two separate occasions). Also, one key type flag that is no longer used by
the library was still defined but not tested, which is not a test gap but is
inconsistent. It's for DSA, which is relevant to the PSA encoding even if
Mbed TLS doesn't implement it, so keep the flag and do test it.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
The status of signature wildcards with respect to PSA_ALG_IS_HASH_AND_SIGN
is unclear in the specification. A wildcard is usually instantiated with a
specific hash, making the implementation hash-and-sign, but it could also be
instantiated with a non-hash-and-sign algorithm. For the time being, go with
what's currently implemented, which is that they are considered
hash-and-sign.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
The current definition of PSA_ALG_IS_HASH_AND_SIGN includes
PSA_ALG_RSA_PKCS1V15_SIGN_RAW and PSA_ALG_ECDSA_ANY, which don't strictly
follow the hash-and-sign paradigm: the algorithm does not encode a hash
algorithm that is applied prior to the signature step. The definition in
fact encompasses what can be used with psa_sign_hash/psa_verify_hash, so
it's the correct definition for PSA_ALG_IS_SIGN_HASH. Therefore this commit
moves definition of PSA_ALG_IS_HASH_AND_SIGN to PSA_ALG_IS_SIGN_HASH, and
replace the definition of PSA_ALG_IS_HASH_AND_SIGN by a correct one (based
on PSA_ALG_IS_SIGN_HASH, excluding the algorithms where the pre-signature
step isn't to apply the hash encoded in the algorithm).
In the definition of PSA_ALG_SIGN_GET_HASH, keep the condition for a nonzero
output to be PSA_ALG_IS_HASH_AND_SIGN.
Everywhere else in the code base (definition of PSA_ALG_IS_SIGN_MESSAGE, and
every use of PSA_ALG_IS_HASH_AND_SIGN outside of crypto_values.h), we meant
PSA_ALG_IS_SIGN_HASH where we wrote PSA_ALG_IS_HASH_AND_SIGN, so do a
global replacement.
```
git grep -l IS_HASH_AND_SIGN ':!include/psa/crypto_values.h' | xargs perl -i -pe 's/ALG_IS_HASH_AND_SIGN/ALG_IS_SIGN_HASH/g'
```
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Only tested for algorithms for which we support HMAC, since that's all we
use PSA_HASH_BLOCK_LENGTH for at the moment.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Set the build type to Release (-O2) when running CPU-intensive tests (ssl-opt,
or unit tests with debug features). A build type of Check (-Os) would be best
when the main objective of the build is to check for build errors or warnings
and there aren't many tests to run; in this commit there are no such test
cases to change. Only use cmake with no build type (which results in not
passing a -O option, and thus missing some GCC warnings) when exercising cmake
features.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Use Release mode (-O2) for component_test_full_cmake_clang which runs SSL
tests.
To have some coverage with Check mode (which enables more compiler warnings
but compiles with -Os), change a few other builds that only run unit tests
at most to Check mode.
Don't add any new builds, to keep the total build volume down. We don't need
extensive coverage of all combinations, just a reasonable set.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
SSL testing benefits from faster executables, so use -O2 rather than -O1.
Some builds use -O1, but that's intended for jobs that only run unit tests,
where the build takes longer than the tests.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
PSA_ALG_RSA_PSS algorithm now accepts only the same salt length for
verification that it produces when signing, as documented.
Fixes#4946.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Test the following combinations:
* 1024-bit key, SHA-256, salt=0
* 1024-bit key, SHA-256, salt=31 (1 byte shorter than standard)
* 1024-bit key, SHA-256, salt=32 (standard length)
* 1024-bit key, SHA-256, salt=94 (maximum possible length)
* 1024-bit key, SHA-512, salt=61 (1 byte shorter than standard)
* 1024-bit key, SHA-512, salt=62 (standard = maximum possible length)
* 528-bit key, SHA-512, salt=0 (only possible length)
Test psa_verify_hash() for both PSA_ALG_RSA_PSS and PSA_ALG_RSA_PSS_ANY_SALT
with all of these combinations. For psa_verify_message(), just test once
with the standard length and once with a different length.
Note that as of this commit, both PSA_ALG_RSA_PSS and
PSA_ALG_RSA_PSS_ANY_SALT accept any salt length during verification, hence
all the new test cases are positive.
The verify test cases were generated using the Python script below.
```
from Cryptodome import Hash
from Cryptodome.Hash import SHA512
from Cryptodome import PublicKey
from Cryptodome.PublicKey import RSA
from Cryptodome.Signature import pss
key = {
528: RSA.import_key(bytes.fromhex("30820145020100024300e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f0203010001024300b166322e09504a5c274b83592f5cf8ce2793a96de5a265abdbe060c641dbc65db0d11c782fe133a7e60aea686d21058d928cad3ef58924c4bb26b9206a03001d0241022200f85d72e463b406ffa282c34b5f0c2d6c2aacf210246af53d5bc7a0b7fa036e1cdb022200ea176c3d9a7fb355fb9fb7707e679b4acfb7bcb645b907e27cdf1764bc340971cd02212e13380342b3dd3083777abf7acc8988ad8a1406069b890f6efd63c57dae31394d022200c3602d3cf537e3cbbda93e072bd8f92965586aae8e5eb20ffc3c8e5fcb1c7b4d7902220098a04f18e48c689ad2f5b9bd404333def54cb2506cd0075c967a2968261e8b8f10")),
1024: RSA.import_key(bytes.fromhex("3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24")),
}
hash_module = {
256: Hash.SHA256,
512: Hash.SHA512,
}
def print_test_case(remark, pub, kbits, hbits, input, output):
key_hex = pub.hex()
input_hex = input.hex()
output_hex = output.hex()
print(f"""\
PSA verify hash: RSA-{kbits} PSS SHA-{hbits}, {remark}
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_{hbits}:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"{key_hex}":PSA_ALG_RSA_PSS(PSA_ALG_SHA_{hbits}):"{input_hex}":"{output_hex}"
PSA verify hash: RSA-{kbits} PSS-any-salt SHA-{hbits}, {remark}
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_{hbits}:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"{key_hex}":PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_{hbits}):"{input_hex}":"{output_hex}"
""")
def rand(n):
return bytes(x & 0xff for x in range(n))
def test_case(kbits, hbits, slen):
priv = key[kbits]
pub_spki = priv.publickey().export_key('DER')
pub_raw = PublicKey._expand_subject_public_key_info(pub_spki)[1]
hash_op = hash_module[hbits].new(b'abc')
digest = hash_op.copy().digest()
output = pss.new(priv, salt_bytes=slen, rand_func=rand).sign(hash_op)
print_test_case(f"slen={slen}", pub_raw, kbits, hbits, digest, output)
test_case(1024, 256, 0)
test_case(1024, 256, 31)
test_case(1024, 256, 32)
test_case(1024, 256, 94)
test_case(1024, 512, 61)
test_case(1024, 512, 62)
test_case(528, 512, 0)
```
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Ensure the unique part fits in the 66 columns that the test runner displays.
Leave room for an additional distinguisher on signature key policy negative
test cases.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>