Commit graph

205 commits

Author SHA1 Message Date
Jaeden Amero
0794936411 Merge pull request #102 from ARMmbed/dev/Patater/fix-allsh
Fix various issues caught by all.sh
2018-09-12 16:41:11 +03:00
Jaeden Amero
b4fa8c9c6d psa: Fix Doxygen comment on psa_get_key_from_slot
We failed all.sh on the "test: doxygen markup outside doxygen blocks" due
to doxygen markup being outside a Doxygen block. Add an extra `*` to the
psa_get_key_from_slot comment to denote the comment as a Doxygen comment.
2018-09-12 16:41:11 +03:00
Gilles Peskine
fe11951c16 Rename psa cipher functions to psa_cipher_xxx
Make function names for multipart operations more consistent (cipher
edition).

Rename symmetric cipher multipart operation functions so that they all
start with psa_cipher_:

* psa_encrypt_setup -> psa_cipher_encrypt_setup
* psa_decrypt_setup -> psa_cipher_decrypt_setup
* psa_encrypt_set_iv -> psa_cipher_set_iv
* psa_encrypt_generate_iv -> psa_cipher_generate_iv
2018-09-12 16:41:11 +03:00
Gilles Peskine
2a91d612f5 Merge remote-tracking branch 'psa/pr/94' into feature-psa 2018-09-12 16:41:11 +03:00
Gilles Peskine
fbfac6867b Simplify algorithm checking logic in MAC functions
Use if-else-if chains rather than switch because many blocks apply to
a class of algoritmhs rather than a single algorithm or a fixed set
of algorithms.

Call abort on more error paths that were missed earlier.
2018-09-12 16:41:11 +03:00
Janos Follath
279ab8e69b Prevent leaking plaintext in psa_cipher_finish() 2018-09-12 16:41:11 +03:00
Gilles Peskine
5d0b864944 Streamline cleanup logic in MAC finish
Reorganize error handling code in psa_mac_finish_internal,
psa_mac_sign_finish and psa_mac_verify finish to ensure that:

* psa_mac_abort() is always called, on all success and error paths.
* psa_mac_finish places a safe value in the output parameters on
  all error paths, even if abort fails.
2018-09-12 16:41:11 +03:00
Janos Follath
315b51c22d Fix memory leak in psa_cipher_finish() 2018-09-12 16:41:11 +03:00
Gilles Peskine
89167cb597 Split psa_mac_setup -> psa_mac_{sign,verify}_setup
Make function names for multipart operations more consistent (MAC
setup edition).

Split psa_mac_setup into two functions psa_mac_sign_setup and
psa_mac_verify_setup. These functions behave identically except that
they require different usage flags on the key. The goal of the split
is to enforce the key policy during setup rather than at the end of
the operation (which was a bit of a hack).

In psa_mac_sign_finish and psa_mac_verify_finish, if the operation is
of the wrong type, abort the operation before returning BAD_STATE.
2018-09-12 16:41:11 +03:00
Gilles Peskine
acd4be36fa Rename psa_mac_{finish,verify} -> psa_mac_{sign,verify}_finish
Make function names for multipart operations more consistent (MAC
finish edition).
2018-09-12 16:41:11 +03:00
Gilles Peskine
da8191d1cd Rename psa_hash_start -> psa_hash_setup
Make function names for multipart operations more consistent (hash
edition).
2018-09-12 16:41:11 +03:00
Gilles Peskine
ab1d7ab89f Don't call psa_get_key_information internally
When you have a key slot pointer, read the key type directly, and call
psa_get_key_bits to get the bit size.
2018-09-12 16:41:11 +03:00
Mohammad Abo Mokh
a5c7b7d0dd Style fixes 2018-09-12 16:41:11 +03:00
Gilles Peskine
b870b188ad New internal function psa_get_key_bits
Isolate the code of psa_get_key_information that calculates the bit
size of a key into its own function which can be called by functions
that have a key slot pointer.
2018-09-12 16:41:11 +03:00
mohammad1603
2701005b46 Modifications for psa-crypto in order to integrate with SPM
Add required includes in tests and psa_crypto.c file in order to be able to compilef for the SPM solution.
Some functions needed to be deprecated from psa_crypto.c since they already implemented in the SPM.
2018-09-12 16:41:11 +03:00
Gilles Peskine
b0b255c82a Always access key slots through accessor functions
New functions psa_get_key_slot(), psa_get_empty_key_slot(),
psa_get_key_from_slot() to access a key slot object from a key slot
number. These functions perform all requisite validations:

* psa_get_key_slot() verifies that the key slot number is in range.
* psa_get_empty_key_slot() verifies that the slot is empty.
* psa_get_key_from_slot() verifies that the slot contains a key with
  a suitable policy.

Always use these functions so as to make sure that the requisite
validations are always performed.
2018-09-12 16:41:11 +03:00
Gilles Peskine
1d96fff61a In psa_mac_finish, write a safe output even in the BAD_STATE case 2018-09-12 16:41:11 +03:00
Gilles Peskine
aee13338b3 Fix safe output length in hash and mac finish
In psa_hash_finish and psa_mac_finish_internal, set the fallback
output length (which is reported on error) to the output buffer size,
not to the _expected_ buffer size which could be larger.
2018-09-12 16:41:11 +03:00
Gilles Peskine
1ae051409f Fix memory leak when importing an RSA key that is too large 2018-09-12 16:41:11 +03:00
Gilles Peskine
46f1fd7afd Handle null pointers safely when used as buffers of size 0
When the size of a buffer is 0, the corresponding pointer argument may
be null. In such cases, library functions must not perform arithmetic
on the pointer or call standard library functions such as memset and
memcpy, since that would be undefined behavior in C. Protect such
cases.

Refactor the storage of a 0-sized raw data object to make it store a
null pointer, rather than depending on the behavior of calloc(1,0).
2018-09-12 16:41:11 +03:00
Jaeden Amero
bbf97e3cf1 psa: Pass hash_length with explicit types
The RSA module uses unsigned int for hash_length. The PSA Crypto API
uses size_t for hash_length. Cast hash_length to unsigned int when
passed to the hash module.
2018-09-12 16:41:11 +03:00
Jaeden Amero
23bbb757ad psa: Pass the number of bits with explicit types
The GCM, CCM, RSA, and cipher modules inconsistently use int or unsigned
int for a count of bits. The PSA Crypto API uses size_t for counting
things. This causes issues on LLP64 systems where a size_t can hold more
than an unsigned int. Add casts for where key_bits and bits are passed to
mbedtls_* APIs.
2018-09-12 16:41:11 +03:00
Jaeden Amero
5390f69590 psa: Use type of block_size consistently
Use size_t for block_size in psa_mac_abort() because
psa_get_hash_block_size() returns a size_t. This also helps to avoid
compiler warnings on LLP64 systems.
2018-09-12 16:41:11 +03:00
Jaeden Amero
045bd50a78 psa: Use key slot type in mbedtls_psa_crypto_free()
To avoid a possible loss of precision, and to be semantically correct,
use psa_key_slot_t (which is 16 bits) instead of size_t (which is 32 or
64 bits on common platforms) in mbedtls_psa_crypto_free().
2018-09-12 16:41:11 +03:00
Jaeden Amero
65fb236799 psa: Make psa_set_key_lifetime() match declaration
Previously, the psa_set_key_lifetime() implementation did not match the
function declaration in psa/crypto.h. Value types don't need const,
since they are passed by value. Fix psa_set_key_lifetime()
implementation by making it match its declaration in the header.
2018-09-12 16:41:11 +03:00
Gilles Peskine
af3baabd05 Define max sizes for MAC and signatures
This requires defining a maximum RSA key size, since the RSA key size
is the signature size. Enforce the maximum RSA key size when importing
or generating a key.
2018-09-12 16:41:11 +03:00
Gilles Peskine
a26ff6a290 psa_asymmetric_sign: consistently fill unused output with '!'
Fill the unused part of the output buffer with '!', for consistency
with hash and mac.

On error, set the output length to the output buffer size and fill the
output buffer with '!', again for consistency with hash and mac. This
way an invalid output is more visible in a memory dump.

Restructure the error paths so that there is a single place where the
unused part of the output buffer is filled.

Also remove a redundant initialization of *signature_length to 0.
2018-09-12 16:41:11 +03:00
Gilles Peskine
2b450e3a01 Factor RSA sign/verify code into its own functions
This makes the functions smaller and makes error paths easier to read.
2018-09-12 16:41:11 +03:00
Gilles Peskine
eae6eee24c Change ECDSA signature representation to r||s
Change the representation of an ECDSA signature from the ASN.1 DER
encoding used in TLS and X.509, to the concatenation of r and s
in big-endian order with a fixed size. A fixed size helps memory and
buffer management and this representation is generally easier to use
for anything that doesn't require the ASN.1 representation. This is
the same representation as PKCS#11 (Cryptoki) except that PKCS#11
allows r and s to be truncated (both to the same length), which
complicates the implementation and negates the advantage of a
fixed-size representation.
2018-09-12 16:41:11 +03:00
Gilles Peskine
a81d85b732 Sort out ECDSA mechanisms
* Distinguish randomized ECDSA from deterministic ECDSA.
* Deterministic ECDSA needs to be parametrized by a hash.
* Randomized ECDSA only uses the hash for the initial hash step,
  but add ECDSA(hash) algorithms anyway so that all the signature
  algorithms encode the initial hashing step.
* Add brief documentation for the ECDSA signature mechanisms.
* Also define DSA signature mechanisms while I'm at it. There were
  already key types for DSA.
2018-09-12 16:24:51 +03:00
Gilles Peskine
526fab0066 Fix parameter name signature_size for psa_asymmetric_verify
It should have been signature_length, following our conventions.
2018-09-12 16:24:51 +03:00
Gilles Peskine
e9191ff90b Add missing const for signature parameter of psa_asymmetric_verify 2018-09-12 16:24:51 +03:00
Gilles Peskine
55bf3d1171 Sort out RSA mechanisms
* PSS needs to be parametrized by a hash.
* Don't use `_MGF1` in the names of macros for OAEP and PSS. No one
  ever uses anything else.
* Add brief documentation for the RSA signature mechanisms.
2018-09-12 16:24:51 +03:00
Gilles Peskine
7ed29c56f1 Rename PSA_ALG_RSA_GET_HASH to PSA_ALG_SIGN_GET_HASH
And don't use it for HMAC when there's a perfectly serviceable
PSA_ALG_HMAC_HASH. HMAC isn't hash-and-sign.
2018-09-12 16:24:50 +03:00
Gilles Peskine
c648d6949d psa_import_key: fix memory leak on error
Free the content of the pk object if an error occurs after the import.
2018-09-12 16:24:50 +03:00
Jaeden Amero
f24c7f80a0 psa_export_key: Always set a valid data length
Make psa_export_key() always set a valid data_length when exporting,
even when there are errors. This makes the API easier to use for buggy
programs (like our test code).

Our test code previously used exported_length uninitialized when
checking to see that the buffer returned was all zero in import_export()
in the case where an error was returned from psa_export_key().
Initialize exported_length to an invalid length, and check that it gets
set properly by psa_export_key(), to avoid this using export_length
uninitialized. Note that the mem_is_zero() check is still valid when
psa_export_key() returns an error, e.g. where exported_length is 0, as
we want to check that nothing was written to the buffer on error.

Out test code also previous passed NULL for the data_length parameter of
psa_export_key() when it expected a failure (in key_policy_fail()).
However, data_length is not allowed to be NULL, especially now that we
write to data_length from psa_export_key() even when there are errors.
Update the test code to not pass in a NULL data_length.
2018-09-12 16:24:50 +03:00
Gilles Peskine
8173631d7e psa_hash_abort: return PSA_SUCCESS if alg=0
Make psa_hash_abort consistent with psa_mac_abort and
psa_cipher_abort.

Add a comment explaining the reasoning.
2018-09-12 16:24:50 +03:00
Gilles Peskine
f9c2c09810 In abort functions, return BAD_STATE on obviously bad input
psa_hash_abort, psa_mac_abort and psa_cipher_abort now return
PSA_ERROR_BAD_STATE if operation->alg is obviously not valid, which
can only happen due to a programming error in the caller or in the
library. We can't detect all cases of calling abort on uninitialized
memory but this is dirt cheap and better than nothing.
2018-09-12 16:24:50 +03:00
Gilles Peskine
48c0ea14c6 Remove PSA_KEY_TYPE_IS_RAW_BYTES from crypto.h
It isn't used to define other macros and it doesn't seem that useful
for users. Remove it, we can reintroduce it if needed.

Define a similar function key_type_is_raw_bytes in the implementation
with a clear semantics: it's a key that's represented as a struct
raw_data.
2018-09-12 16:24:50 +03:00
Gilles Peskine
9ad29e2bee Add what little was missing to fully support DES
Also add what was missing in the test suite to support block ciphers
with a block size that isn't 16.

Fix some buggy test data that passed only due to problems with DES
support in the product.
2018-09-12 16:24:50 +03:00
Gilles Peskine
9a94480685 Convert ERR_ASN1 error codes to PSA
This fixes the error code when psa_export_key on an asymmetric key
reports that the output buffer is too small.
2018-09-12 16:24:50 +03:00
Gilles Peskine
b54979a297 Refuse non-byte-sized raw data keys
Since the key size is stored in bytes, we can't have a key whose size
isn't a whole number of bytes.
2018-09-12 16:24:50 +03:00
Gilles Peskine
c06e07128c Favor INVALID_ARGUMENT over NOT_SUPPORTED for bad algorithm types
In psa_hash_start, psa_mac_start and psa_cipher_setup, return
PSA_ERROR_INVALID_ARGUMENT rather than PSA_ERROR_NOT_SUPPORTED when
the algorithm parameter is not the right category.
2018-09-12 16:23:54 +03:00
Gilles Peskine
248051acb6 Add missing #ifdef guards around psa_hmac_start 2018-09-12 16:23:54 +03:00
Gilles Peskine
16c0f4f787 Fix potential memory corruption on MAC/cipher setup failure
When psa_mac_start(), psa_encrypt_setup() or psa_cipher_setup()
failed, depending on when the failure happened, it was possible that
psa_mac_abort() or psa_cipher_abort() would crash because it would try
to call a free() function uninitialized data in the operation
structure. Refactor the functions so that they initialize the
operation structure before doing anything else.

Add non-regression tests and a few more positive and negative unit
tests for psa_mac_start() and psa_cipher_setup() (the latter via
psa_encrypt_setip()).
2018-09-12 16:23:53 +03:00
Gilles Peskine
12313cd84c Implement psa_generate_key: AES, DES, RSA, ECP
In the test cases, try exporting the generated key and perform sanity
checks on it.
2018-09-12 16:22:51 +03:00
Gilles Peskine
e66ca3bbf3 psa_export_key: zero out potential garbage in the output buffer
In psa_export_key, ensure that each byte of the output buffer either
contains its original value, is zero, or is part of the actual output.
Specifically, don't risk having partial output on error, and don't
leave extra data at the end of the buffer when exporting an asymmetric
key.

Test that exporting to a previously zeroed buffer leaves the buffer
zeroed outside the actual output if any.
2018-09-12 16:22:51 +03:00
Gilles Peskine
0e2315859f psa_export_key: fix asymmetric key in larger buffer
Exporting an asymmetric key only worked if the target buffer had
exactly the right size, because psa_export_key uses
mbedtls_pk_write_key_der or mbedtls_pk_write_pubkey_der and these
functions write to the end of the buffer, which psa_export_key did not
correct for. Fix this by moving the data to the beginning of the
buffer if necessary.

Add non-regression tests.
2018-09-12 16:22:51 +03:00
Gilles Peskine
05d69890ee Implement psa_generate_random 2018-09-12 16:22:51 +03:00
Gilles Peskine
0ff4b0f7f9 psa_import_key: validate symmetric key size
When importing a symmetric key, validate that the key size is valid
for the given key type.

Non-supported key types may no longer be imported.
2018-09-12 16:22:51 +03:00