aboutsummaryrefslogtreecommitdiff
path: root/libstb
AgeCommit message (Collapse)AuthorFilesLines
2022-06-13libstb: Fix memcpy overread in fakenv_readpublic()Reza Arbab1-2/+2
Caught by `make check` on fedora-rawhide (GCC 12): libstb/secvar/test/../storage/fakenv_ops.c: In function 'fakenv_readpublic': libstb/secvar/test/../storage/fakenv_ops.c:155:17: error: 'memcpy' reading 134 bytes from a region of size 34 [-Werror=stringop-overread] 155 | memcpy(&nv_name->t.name, tpmnv_vars_name, sizeof(TPM2B_NAME)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from libstb/secvar/test/secvar-test-secboot-tpm.c:5: libstb/secvar/test/../storage/secboot_tpm.c:35:15: note: source object 'tpmnv_vars_name' of size 34 35 | const uint8_t tpmnv_vars_name[] = { | ^~~~~~~~~~~~~~~ libstb/secvar/test/../storage/fakenv_ops.c:158:17: error: 'memcpy' reading 134 bytes from a region of size 34 [-Werror=stringop-overread] 158 | memcpy(&nv_name->t.name, tpmnv_control_name, sizeof(TPM2B_NAME)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ libstb/secvar/test/../storage/secboot_tpm.c:41:15: note: source object 'tpmnv_control_name' of size 34 41 | const uint8_t tpmnv_control_name[] = { | ^~~~~~~~~~~~~~~~~~ The source and destination of each memcpy have known sizes, and we are copying the smaller buffer into the larger one, so change the memcpy size to that of the smaller buffer. Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
2022-06-13libstb: Work around deprecated API warnings on OpenSSL 3.0 systemsReza Arbab1-0/+1
Several OpenSSL APIs that libstb uses have been deprecated in OpenSSL 3.0. Commit 9a1f95f87004 ("libstb/create-container: avoid using deprecated APIs when compiling with OpenSSL 3.0") enabled `make` to succeed on an OpenSSL 3.0 system, but `make check` still fails: libstb/print-container.c:405:9: error: 'EC_KEY_new' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] libstb/print-container.c:413:9: error: 'EC_KEY_set_group' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] libstb/print-container.c:425:9: error: 'EC_POINT_bn2point' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] libstb/print-container.c:429:9: error: 'EC_KEY_set_public_key' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] libstb/print-container.c:434:9: error: 'ECDSA_do_verify' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] libstb/print-container.c:449:9: error: 'EC_KEY_free' is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] This print-container.c is derived from the one in the sb-signing-utils project. Ideally, OpenSSL 3.0 support should be added there first and then synced back into skiboot. Until that is complete[1], build with -Wno-error=deprecated-declarations so these errors stop blocking our CI. [1] https://github.com/open-power/sb-signing-utils/issues/35 Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
2022-03-16libstb/create-container: avoid using deprecated APIs when compiling with ↵Eric Richter1-1/+9
OpenSSL 3.0 OpenSSL 3.0 has deprecated functions that operate on raw key data, however the closest replacement function are not available in OpenSSL 1.x. This patch attempts to maintain compatibility with both 3.0 and 1.x versions. Avoids using the following deprecated functions when compiling with 3.0: - EC_KEY_get0_group - EC_KEY_get0_public_key - EC_POINT_point2bn - EC_KEY_free Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
2021-12-09secvar/pkcs7: fix a wrong sizeof()Daniel Axtens1-1/+1
This code isn't directly used by skiboot, but it is wrong and potentially insecure so I'm fixing it in case it's used in the future. We pass sizeof(hash) into mbedtls_pk_verify(). However, hash is a pointer, not an array, so rather than passing the length of the hash to verify we'll pass in 8, and only compare the first 8 bytes of the hash rather than all 32. Pass in 0 instead. That tells mbedtls to work out the length based on the hash type. We allocated enough memory for whatever hash type the PKCS#7 message declared so this will be safe. Signed-off-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Cédric Le Goater <clg@kaod.org>
2021-11-04secvar/edk2: store timestamp variable in protected storageEric Richter2-1/+4
Each signed variable update contains a timestamp -- this timestamp is checked against the previous timestamp seen for that particular variable (if any), and the update is rejected if the timestamp is not a later time than the previous. This timestamp check is intended to prevent re-use of signed update files. Currently, the code stores the timestamps in the TS variable, which is then stored in regular variable storage (typically PNOR). This patch promotes the variable to "protected storage" (typically TPM NV), so avoid this variable being accidentally cleared. This change should only come into effect when either: - initializing secvar for the first time (i.e. first boot, or after a key-clear-request) - processing any variable update Systems that already have a TS variable in PNOR will not be affected until either of the above actions are taken. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Tested-by: Nick Child <nick.child@ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Cédric Le Goater <clg@kaod.org>
2021-11-04secvar/secboot_tpm: unify behavior for bank hash check and secboot header checkEric Richter2-16/+29
As the PNOR variable space cannot be locked, the data must be integrity checked when loaded to ensure it has not beeen modified by an unauthorized party. In the event that a modification has been detected (i.e. hash mismatch), we must not load in data that could potentially be compromised. However, the previous code was a bit overzealous with its reaction to detecting a compromised SECBOOT partition, and also had some inconsistencies in behavior. Case 1: SECBOOT partition cleared. .init() checks the header for the magic number and version. As neither matches, will reformat the entire partition. Now, .load_bank() will pass, as the data was just freshly reformatted (note: this also could trigger the bug addressed in the previous patch). Only variables in the TPM will be loaded by .load_bank() as the data in SECBOOT is now empty. Case 2: Bank hash mismatch. .load_bank() panics and returns an error code, causing secvar_main() to jump to the error scenario, which prevents the secvar API from being exposed. os-secure-enforcing is set unconditionally, and the user will have no API to manage or attempt to fix their system without issuing a key clear request. This patch unifies the behavior of both of these cases. Now, .init() handles checking the header AND comparing the bank hash. If either check fails, the SECBOOT partition will be reformatted. Variables in the TPM will still be loaded in the .load_bank() step, and provided the backend stores its secure boot state in the TPM, secure boot state can be preserved. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Tested-by: Nick Child <nick.child@ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Cédric Le Goater <clg@kaod.org>
2021-11-04secvar/secboot_tpm: correctly reset the control index on secboot formatEric Richter1-4/+7
When the SECBOOT partition is formatted, the bank hash stored in the control TPM NV index must be updated to match, or else we will immediately fail to load the freshly formatted data at the .load_bank() step. However, while the secboot_format() function does calculate and update the bank hash, it only writes the new hash for bank 0. It does not update the value for bank 1, or set the current active bank. This works as expected if the active bank bit happens to be set to 0. On the other hand, if the active bit is set to 1, the freshly formatted bank 1 will be compared against the unchanged bank hash in bank 1 at the load step, therefore causing an error. This patch fixes this issue by also setting the active bit to 0 to match the freshly calculated hash. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Tested-by: Nick Child <nick.child@ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Cédric Le Goater <clg@kaod.org>
2021-09-09secvar: Free md context on hash errorNick Child1-2/+2
There were a few instances in `get_hash_to_verify` where NULL is returned before unallocating the md context. This commit ensures that this memory is properly freed before returning. Signed-off-by: Nick Child <nick.child@ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-27secvar/backend: fix comment of get_hash_to_verifyDaniel Axtens1-1/+1
get_hash_to_verify claims to return a negative error code in the case of error. It actually returns NULL. Fix the comment. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nick Child <nick.child@ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-27secvar/backend: clarify variables in process_updateDaniel Axtens1-8/+6
process_update() has tbhbuffer and tbhbuffersize. However, tbhbuffer doesn't contain to-be-hashed data, but a hash: /* Prepare the data to be verified */ tbhbuffer = get_hash_to_verify(update->key, *newesl, *new_data_size, timestamp); And tbhbuffersize is initalised to zero and then never filled with the actual length, so 0 is passed through to verify_signature. verify_signature will in turn pass that to mbedtls, which will interpret it as "figure out the length yourself based on the hash type". So this has always worked, but by accident. Rename tbhbuffer to hash, as that's what it is. Drop tbhbuffersize, and pass 32 directly to verify_signature. We only support SHA-256, and SHA-256 is 32 bytes long. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nick Child <nick.child@ibm.com> Tested-by: Nick Child <nick.child@ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-27secvar/backend: rename verify_signature parametersDaniel Axtens1-2/+2
verify_signature() currently takes newcert and new_data_len. However, these variables are used only as parameters to mbedtls_pkcs7_signed_hash_verify() where they represent a hash value and the length of the hash value. verify_signature() is static, and the only caller of the function is process_update(). process_update() passes in tbhbuffer and tbhbuffersize. Those are unfortunate names too - because the data that process_update() passes in is not a to-be-hashed buffer, but a hash. We'll fix that later. Call the parameters hash and hash_len. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nick Child <nick.child@ibm.com> Tested-by: Nick Child <nick.child@ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-20pkcs7: pkcs7_get_content_info_type should reset *p on errorDaniel Axtens2-1/+35
Fuzzing revealed a crash where pkcs7_get_signed_data was accessing beyond the bounds of the object, despite valid data being passed in to mbedtls_pkcs7_parse_der. Further investigation revealed that pkcs7_get_content_info_type will reset *p to start if the second call to mbedtls_asn1_get_tag fails, but not if the first call fails. mbedtls_asn1_get_tag does indeed advance *p even in some failure cases, so a reset is required. Reset *p to start if the first call to mbedtls_asn1_get_tag fails. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-20secvar/backend: fix a memory leak in get_pkcs7Daniel Axtens4-1/+181
We need to actually free the pkcs7 structure, not just pass it to mbedtls_pkcs7_free(). Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-20secvar/backend: fix an integer underflow bugDaniel Axtens3-0/+182
If a declared size is smaller than uuid size, we end up allocating with an allocation of a 'negative' number, which is a huge 64 bit number. This will probably then fail with an OPAL_NO_MEM, but it will be better to catch it and return OPAL_PARAMETER instead. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-20secvar/backend: Don't overread data in auth descriptorDaniel Axtens2-0/+22
Catch another OOB read picked up by the fuzzer. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-20secvar: return error if verify_signature runs out of ESLsNick Child2-1/+29
Currently, in `verify_signature`, the return code `rc` is initialized as 0 (our success value). While looping through the ESL's in the given secvar, the function will break if the remaining data in the secvar is not enough to contain another ESL. This break from the loop was not setting a return code, this means that the successful return code can pass to the end of the function if the first iteration meets this condition. In other words, if a current secvar has a size that is less than minimum size for an ESL, than it will approve any update. In response to this bug, this commit will return an error code if the described condition is met. Additionally, a test case has been added to ensure that this unlikely event is handled correctly. Signed-off-by: Nick Child <nick.child@ibm.com> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-20secvar: return error if validate_esl has extra dataNick Child2-1/+19
Currently, in `validate_esl_list`, the return code is initialized to zero (our success value). While looping though the ESL's in the submitted ESL chain, the loop will break if there is not enough data to meet minimum ESL requirements. This condition was not setting a return code, meaning that the successful return code can pass to the end of the function if there is extra data at the end of the ESL. As a consequence, any properly signed update can successfully commit any data (as long as it is less than the min size of an ESL) to the secvars. This commit will return an error if the described condition is met. This means all data in the appended ESL of an auth file must be accounted for. No extra bytes can be added to the end since, on success, this data will become the updated secvar. Additionally, a test case has been added to ensure that this commit addresses the issue correctly. Signed-off-by: Nick Child <nick.child@ibm.com> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-20secvar/backend: use endian-aware types in edk2.hDaniel Axtens1-9/+9
Recently we had an issue where we did the following: uint16_t year = le32_to_cpu(timestamp->year); This is wrong and will break on BE. However, we didn't catch this with sparse because there was a whole slew of warnings. The reason for the slew of warnings is that we didn't annotate the types that store little-endian specific data in edk2.h. Provide the appropriate annotations. We now get a single sparse warning for the file, which correctly identifies the issue: edk2-compat-process.c:374:46: warning: incorrect type in argument 1 (different base types) edk2-compat-process.c:374:46: expected restricted leint32_t [usertype] le_val edk2-compat-process.c:374:46: got restricted leint16_t const [usertype] year We do lose the signedness of efi_time->timezone, but that's probably OK: we never use the timezone anyway and the comment above the data structure makes the signedness pretty clear. Signed-off-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-19secvar: Make `validate_esl_list` iterate through esl chainNick Child3-4/+244
Currently, the loop in validate_esl_list is not iterating through the ESL entries. As a consequence, all of entries after the first are not being validated and can contain any data. In order to iterate, the pointer to the esl buffer must be incremented by the amount of already read bytes. This commit also adds a new test case and file. The file is `multipletrimmedKEK.h` the array is very similar to the one in `trimmedKEK.h` except this one only has an invalid ESL as the second ESL in the chain. This then tests the condition that this commit tests because only the second ESL is invalid. Signed-off-by: Nick Child <nick.child@ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-07-19secvar: ensure ESL buf size is at least what ESL header expectsNick Child3-1/+182
Currently, `get_esl_cert` receives a data buffer containing an ESL and its length. It is to return a data buffer of the certificate that is contained inside the ESL. The ESL has header info that contains the certificates `size` and the size of the header (`sig_data_offset`). We use this information to copy `size` bytes starting `sig_data_offset` bytes after the given ESL buffer. Currently we are checking that the length of the ESL buffer is at least `sig_data_offset` bytes but we are not checking that it also has enough bytes to also contain `size` bytes of the certificate. This becomes problematic if some data at the end of the ESL gets lost. Since the ESL claims it has more than it actually does, this will lead to a buffer over-read. What is even worse, is that this buffer over-read can go unnoticed since the last 256 bytes of the ESL are usually the x509 2048 bit signature so the extra garbage bytes that are copied will appear to be a valid rsa signature. To resolve this, this commit ensures that the ESL buffer length is large enough to hold the data that it claims it contains. Lastly, a new test case is added to test the described condition. It includes a new test file `trimmedKEK.h` which contains a struct a valid KEK auth file minus 5 bytes, therefore making it invalid. Signed-off-by: Nick Child <nick.child@ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-06-25secvar/backend: require sha256 in our PKCS#7 messagesDaniel Axtens3-0/+216
We only handle sha256 hashes in auth structures. In the process of verifying an auth structure, we extract the pkcs7 message and we calculate the hopefully-matching hash, which is sha256(name || vendor guid || attributes || timestamp || newcontent) We then verify that the PKCS#7 signature matches that calculated hash. However, at no point do we check that the PKCS#7 hash algorithm is sha256. So if the PKCS#7 message says that it is a signature on a sha512, mbedtls will compare 64 bytes of hash from the signature with 64 bytes from our hash, resulting in a 32 byte overread. Verify that the hash algorithm in the PKCS#7 message is sha256. Add a test. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Nayna Jain <nayna@linux.ibm.com> Tested-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-06-24secvar: fix endian conversionNayna Jain1-1/+1
unpack_timestamp() calls le32_to_cpu() for endian conversion of uint16_t "year" value. This patch fixes the code to use le16_to_cpu(). Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-05-13secvar/backend: add EFI_CERT_RSA2048_GUIDDaniel Axtens1-0/+2
This isn't currently used in skiboot but may be used by external users of skiboot's secvar code. Signed-off-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-05-13secvar/backend: include short-types.h in edk2.hDaniel Axtens1-0/+1
We use these types but haven't included the header: every file that includes edk2.h has already included it. This might not be true for other users of edk2.h and skiboot's secvar code, so include it explictly. Signed-off-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-05-13secvar/secvar_util: Properly free memory on zalloc failNick Child1-1/+1
If allocating the secure variable name of a secure variable struct, `secvar->key`, fails then the secvar struct should be freed before returning NULL. Previously, if this allocation fails, then only the `secvar->key` is freed (which is likely a typo) leaving the allocated `secvar` struct allocated and returning NULL. This memory leak can be seen with the static analysis tool `cppcheck`. After running valgrind tests, this commit ensures that memory is properly freed if an error occurs when allocating the `key` field of the `secvar` struct. Signed-off-by: Nick Child <nick.child@ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-05-13edk2-compat-process.c: Remove repetitive debug print statementsNick Child1-7/+2
Functions `get_esl_cert`, `validate_esl_list` and `get_esl_signature_list_size` all contain the same debug print statement. This statement prints the size of the ESL. `validate_esl_list` calls `get_esl_cert` so the same debug information prints twice when validating the newly submitted ESL. Additionally, the same debug prints twice when validating the current ESL since `get_esl_cert` and `get_esl_signature_list_size` are both called by the function `verify_signature`. Since `get_esl_cert` is the common factor, this commit removes the other two print statements (and adds some information to an error message to maintain clarity, in case `validate_esl_list` fails before calling `validate_esl_cert`). After double checking that these functions are not being called anywhere else, the only real change is to reduce the number of redundant print statements for the secvar update process. Signed-off-by: Nick Child <nick.child@ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-03-31secvar/backend/edk2.h: mark structs as __packed explicitlyDaniel Axtens1-6/+8
The structes we import from EDK2 are expected to be packed. The code we imported does this a #pragma pack, but it doesn't restore the original non-packed state at the end of the header. Rather than changing that, just explictly pack every structure. The resulting skiboot.elf has the same disassembly (objdump -dr) and readelf -a output, but I haven't been able to test this on a real machine. Signed-off-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2021-02-04libstb/trustedboot: Use inclusive language, replace the word 'whitelist'Philippe Mathieu-Daudé1-1/+1
Follow the inclusive terminology from the "Conscious Language in your Open Source Projects" guidelines [*] and replace the word "whitelist" appropriately. [*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2020-11-27secvar: fix Using plain integer as NULL pointer sparse warningStewart Smith1-1/+1
Signed-off-by: Stewart Smith <stewart@flamingspork.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
2020-10-02secvar/test: use mbedtls cflags when building the test binariesEric Richter2-2/+4
The edk2 test file includes some mbedtls files directly, make sure that those also include the correct mbedtls config file. Without this, the default config file is used, which conflicts with the version we build as part of skiboot. As host libc includes a SIZE_MAX macro, this also changes the SIZE_MAX macro defined in mbedtls_config.h (needed for some mbedtls functions) to only be defined if it isn't already. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-02secvar/test: use vendored mbedtls instead of hostEric Richter2-7/+10
Linking against the host mbedtls introduces problems if the host does not have the library, or if the host has a different version installed. This patch changes the tests to instead build mbedtls from the version included in skiboot using the host compiler, removing the dependency on external mbedtls. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar: Clean up makefiles and fix out of tree buildsOliver O'Halloran4-19/+13
The secvar makefiles use $(SRC) in a few places they shouldn't and don't use it in a few places they should. Also drop the _SRCS rules and the pattern substuituion that turns them into _OBJS rules because chaining dependent rules is infuriating at the best of times. Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/test: Remove broken initalizersOliver O'Halloran1-2/+2
Some versions of GCC complain about this. That and since it's a static global it goes in the BSS and is initialized to zero anyway. Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/backend: improve edk2 driver unit testcasesNayna Jain2-37/+387
This patch adds following more unit test cases and improve comments. * Check for successful processing of queued updates * Check for queued updates when one update fail, especially when PK is added. * Check for queued updates when one update fail, especially when PK is deleted. * Check hw-key-hash addition/deleting/verification. * Update dbxcert file * Update rc checks against specific failure error return codes. Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/backend: Bugfixes in edk2 driverNayna Jain3-14/+37
This patch fixes following bugs. Additionally, it improves logs. * Failure in adding/deleting PK as part of failure of processing any subsequential update in the queue didn't reset the global variable setup_mode to the original value. This patch adds the fix to always set the value of setup_mode as per final contents in variable_bank before existing process(). * Deletion of HWKH as part of deleting PK was only updating the value of the variable to be zero. However, this didn't deallocate the variable from the bank and was getting exposed via sysfs. * The mismatch in verification of hw-key-hash, was also clearing staging bank, which isn't initialized in this case. Fix the cleanup tag to only clear update_bank. * Fixes a memory leak in validate_esl_list(). * Convert signature verification error code from mbedtls into opal error code as OPAL_PERMISSION. Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secboot_tpm.c: increase tpmnv vars index sizeEric Richter3-6/+6
The TPM NV index size for storing the PK was originally set to 1024, which was determined to be a "smallest maximum" size that we determined to be enough to store the PK. However with overhead, this only allowed for about ~912 bytes, which is far too small to store a certificate, as it only permits about ~10 characters in the x509 subject field. This patch increases the TPM NV Vars index to 2048 bytes, which is the largest size a single NV index can be on the Nuvoton npct650 chip. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01tssskiboot.c: chunk reads/writes in 1024-sized buffers to support larger nv ↵Eric Richter1-28/+54
indices The Nuvoton npct650 chip has a command buffer max size of 1024. Attempting to read or write from an NV index larger than this value would return an error. This patch changes the tss_nv_read and tss_nv_write commands to chunk their operations in 1024-byte batches to allow support for larger NV indices. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/test: add edk2-compat driver test and test dataEric Richter17-2/+2448
This patch contains a set of tests to exercise the edk2 driver using actual properly (and in some cases, improperly) signed binary data. Due to the excessive size of the binary data included in the header files, this test was split into its own patch. Co-developed-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/backend: add edk2 derived key updates processingNayna Jain7-2/+1499
As part of secureboot key management, the scheme for handling key updates is derived from tianocore reference implementation[1]. The wrappers for holding the signed update is the Authentication Header and for holding the public key certificate is ESL (EFI Signature List), both derived from tianocore reference implementation[1]. This patch adds the support to process update queue. This involves: 1. Verification of the update signature using the key authorized as per the key hierarchy 2. Handling addition/deletion of the keys 3. Support for dbx (blacklisting of hashes) 4. Validation checks for the updates 5. Supporting multiple ESLs for single variable both for update/verification 6. Timestamp check 7. Allowing only single PK 8. Failure Handling 9. Resetting keystore if the hardware key hash changes [1] https://github.com/tianocore/edk2-staging.git Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01crypto: add out-of-tree mbedtls pkcs7 parserNayna Jain6-1/+848
This patch adds a pkcs7 parser for mbedtls that hasn't yet gone upstream. Once/if that implementation is accepted, this patch can be removed. Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/storage: add utility tool to generate NV public name hashesEric Richter2-0/+110
This patch adds a small userspace utility to locally generate the expected hash returned by a TSS_NV_ReadPublic command for the NV indices as defined by the secboot_tpm storage driver. This removes the need for manually copying in the hash from the ReadPublic output if for some reason the set of attributes used when defining the NV indices changes in the future. As this is an auxiliary tool, it is not built by default and must be manually built using `make gen_tpmnv_public_name`. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/test: add secboot_tpm storage driver test casesEric Richter2-1/+146
This patch adds some simple unit cases to exercise the storage driver, using the fake TPM NV implementation. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/storage/fakenv: add fake tpm operations for testingEric Richter2-0/+178
The secboot_tpm storage driver heavily relies on the TPM to ensure data integrity, which makes it difficult to test in userspace or on hardware without a TPM. This patch adds a bunch of functions that implement the tssskiboot interface, and simulates the expected TPM behavior utilizing PNOR space instead. THIS IS NOT INTENDED FOR PRODUCTION USE. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/storage: add secvar storage driver for pnor-based p9Eric Richter5-4/+818
This patch implements the platform specific logic for persisting the secure variable storage banks across reboots via the SECBOOT PNOR partition. For POWER 9, all secure variables and updates are stored in the in the SECBOOT PNOR partition. The partition is split into three sections: two variable bank sections, and a section for storing updates. The driver alternates writes between the two variable sections, so that the final switch from one set of variables to the next can be as atomic as possible by flipping an "active bit" stored in TPM NV. PNOR space provides no lock protection, so prior to writing the variable bank, a sha256 hash is calculated and stored in TPM NV. This hash is compared against the hash of the variables loaded from PNOR to ensure consistency -- otherwise a failure is reported, no keys are loaded (which should cause skiroot to refuse to boot if secure boot support is enabled). Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar_devtree: add physical presence mode helperEric Richter2-0/+17
This patch adds a simple function to detect whether or not physical presence has been asserted. In the current implementation, all physical presence assertion modes are treated the same. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar/test: update API tests for new secvar structEric Richter3-39/+14
This patch adjusts the API unit tests to use the secvar struct rather than the old secvar_node. Where applicable, some manual allocations have also been replaced with the util functions. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar: overhaul secvar struct by removing static sized fieldsEric Richter3-97/+88
Originally, the secvar struct was intended to contain all the variable information seperate from the linked list/etc metadata, so that copying and serialization/deserialization could be handled by a single memcpy(). This is fragile, potentially compiler dependent, and doesn't account for endianness. Therefore, this patch removes the static allocation for key, now allocates a buffer for data, and completely removes the now unnecessary secvar_node struct. As a side effect, some of the secvar_util functionality has been tweaked where it makes sense. Most notably alloc_secvar now takes in an extra argument as it now has to allocate the key Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar_util: add new helper functionsEric Richter2-3/+65
This patch adds the following helper functions: - dealloc_secvar() - new_secvar() - copy_bank_list() dealloc_secvar() frees a whole secvar_node reference including its children allocations. This also updates the clear_bank_list() helper function to use this destructor. new_secvar() allocates a secvar_node, and fills it with data provided via arguments. copy_bank_list() creates a deep copy of a secvar bank list Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar: change backend hook interface to take in bank referencesNayna Jain1-3/+3
Previously, backends were implicitly expected to operate on global references to the variable and update banks. This patch changes the interface for this driver to instead take the banks in as an argument. This removes the implict dependency on these references, makes the design consistent with the storage driver, and also will simplify unit testing of these functions. Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
2020-10-01secvar_main: rework secvar_main error flow, make storage locking explicitEric Richter1-14/+67
This patch adjusts the behavior of secvar_main to actually halt the boot in some form if there is an issue initializing secure variables. The secvar storage driver contains the secure boot state, and therefore if that fails to initialize, we immediately need to halt the boot. For all other cases we enforce secure boot in the bootloader by setting the secure mode flag, but booting with an empty keyring (and thus, cannot verify a kexec image). Previously, the storage driver was expected to handle any locking procedures implicitly as part of the write operation. This patch uses the new lockdown hook which makes locking explicit and part of the secvar_main flow. The storage driver is now locked unconditionally when exiting secvar_main, and the lockdown() call should halt the boot if it encounters any sign of struggle. Signed-off-by: Eric Richter <erichte@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>