Published
- 21 min read
Exploring Vulnerabilities in the SDLS Implementation of NASA’s CryptoLib
Introduction
As a Young Graduate Trainee in the system security engineering team in ESTEC, I was assigned the task to analyse the security of the protocols used in space communications between the ground and the space segment. The scope was large, including many protocols, standards (CCSDS & ECSS) and different implementations but a challenging opportunity to learn. These activities lead to some tools development providing a toolset called SPACE-SAT (Space Protocol Analysis, CCSDS & ECSS Security Assessment Toolset). This article is an outcome of these activities which describes multiple vulnerabilities identified in the NASA Crytolib software v1.3.[0,1], a software-only solution implementing the Space Data Link Security protocol (SDLS), used to secure space communication between a ground segment and a spacecraft.
The identified vulnerabilities enable an attacker to send arbitrary telecommands to a spacecraft’s Onboard Computer (OBC), potentially causing unwanted behaviors. More critically, the attacker could gain exclusive control of the spacecraft. In other words, the attacker can execute any action, completely bypassing the SDLS implementation, and even leverage the SDLS implementation to block access to the legitimate operator.
In this article, I begin by describing the out-of-bounds vulnerability and explaining how it can be exploited to bypass SDLS. Next, I introduce a new vulnerability that also allows an attacker to send commands to the spacecraft, bypassing SDLS. I then discuss another vulnerability in the SDLS Extended Procedure implementation, which enables the attacker to hijack a satellite. Following that, I explain how to decrypt legitimate telecommands without knowing the key. Finally, I outline the V&V (Verification and Validation) strategy of CryptoLib regarding security and present the vulnerability patches.
Background on the Space Data Link Security Protocol
The Space Data Link Security Protocol (SDLS) is layer 2 protocol standardized by the Consultative Committee for Space Data Systems (CCSDS). It aims to secure the frame data payload between the mission control system (MCS) and the satellite through three provided security services:
- authentication (including integrity protection)
- encryption
- authenticated encryption.
A fourth service is also standardized but less well known as it is not recommended: Clear Mode or transparent mode. With this service, the SDLS protocol header is present, but no cryptographic operation is performed. Therefore, this solution doesn’t provide any form of security.
For all the security services offered by SDLS, a security header and (optionally) a trailer are added to the frames providing the necessary contextual information used by the receiving end to perform security verification as shown on Figure 1.
SDLS is a stateful protocol relying on Security Associations (SA) stored in sending and receiving ends (mission control system and spacecraft) defining the cryptographic communications parameters to perform one of the four mentioned services. The receiver uses the Security Parameter Index (SPI) within the security header to reference the corresponding SA. With the frame security fields and SA, the receiving end can perform security verification.
To manage an implementation of the SDLS protocol, a set auxiliary services have been standardized called SDLS Extended Procedures. These commands allow the spacecraft operator to manage the security parameters of SDLS (Key Management, SA management, Monitoring and Control). For instance, the operator can upalod a new key into the spacecraft memory or change an SA state from Operational to Expire.
For a further understanding of SDLS, I would suggest having a look to the Space Data Link Protocol Security blue book
Crashing CryptoLib
To complete the development of SPACE-SAT, others CCSDS compliant implementations were necessary to cross-check my implementation. The NASA CrytoLib was one of them, providing two main security functions for the TC, TM and AOS data link protocols:
- Crypto_[TC,TM,AOS]_ApplySecurity: to generate a SDLS compliant frame from a valid frame
- Crypto_[TC,TM,AOS]_ProcessSecurity: to parse and perform security verification of a SDLS frame.
The Crypto_TC_ProcessSecurity function is certainly the most interesting function in the context of spacecraft security assessment. It is the first protection (sometimes the only one) interfacing with the terrestrial world (similar to a https server on the web but a bit more challenging to reach). Consequently, potential malicious actors could also attempt to send frames to this interface.
One of the features of SPACE-SAT is a basic fuzzer functionality, providing the capability to fuzz selected fields of the implemented protocols by replacing their values with a random numbers. This allows to perform a first robustness test of space protocols parsers. I cross-checked the tool against the CryptoLib process security program (a small interface for testing the functions) and the test worked but it was also proven to be successful quickly. By fuzzing the SPI, many values lead to a segmentation fault as shown in Figure 2.
Since CryptoLib is open-source, it was straightforward to identify the cause of the crash. CryptoLib uses a C structure to represent each SA which are stored in a static array (a common practice in embedded system to better manage memory) and uses the SPI as array index (e.g. SA 1 is accessed by sa[1]). With this memory management, the implementation could require a lot of memory as there is 65536 SPI available as per the standard and each SA structure is around 200MB in the current implementation. To limit the memory consumption, the CryptoLib developers defined a preprocessor directive NUM_SA which narrows the number of available SA (64 by default). However, they did not introduce a check in the program for the SPI values between the maximum allowed by the standard and the maximum supported by their implementation. So, if the provided SPI is not in the range of [0, NUM_SA], the program would still use the SPI to read memory located at sa[SPI] . This leads to an out-of-bounds read vulnerability. This vulnerability was disclosed in the summer of 2024 by VisionSpace through the CVE-2024-44911 and it was fixed by checking if the parsed SPI is in the range [0, NUM_SA]. The CVE is impacting the availability of the spacecraft, but, as we will see in the next sections, the authenticity of the telecommands can also be impacted.
Crashing implications of CryptoLib
SDLS is a library providing cryptographic services relying on states (stateful implementation). In the context of SDLS, two main values must be tracked to ensure secure communication:
- Anti Replay Sequence Number (ARSN)
- Initialisation Vector (IV)
The ARSN protects the system against replay attacks while the IV ensures that two plaintext blocks will not have the same ciphertext even with the same key. In AES-GCM, the initialisation vector which increments by one for each new frame, is holding the ARSN. This counter is sent in the request, and its value is carefully tracked by the MCS and the spacecraft. In the case of CryptoLib, the counter is kept in volatile memory in the spacecraft. Therefore, when the out-of-bounds vulnerability is exploited, not only does it make the service unavailable for a moment, but it also resets the cryptographic counters (in VisionSpace’s video article, the Core Fly System (cFS) reboots after the segfault with a new instance). If no procedure is defined to handle this situation in a secure way, the spacecraft would be vulnerable to TC replay attacks and its TM frame would use the same IV (IV reuse) after reboot. An attacker with the capabilities to sniff legitimate commands could replay them as much as he wants, since he would only need to reboot the system with the out-of-bounds read vulnerability to make the command valid again. Therefore, the out-of-bounds read vulnerability to crash the system can also lead to an integrity problem with SDLS implementations.
Exploit the out-of-bounds read vulnerability to bypass SDLS
With the out-of-bounds read vulnerability, we have the capability to read arbitrary memory but not on the full memory space. While focusing on typical C exploitations such as Remote Code Execution, I couldn’t find any path, so I decided to take a step back and took into consideration the specificity of SDLS, especially the Clear Mode presented above. I was thinking that potentially SDLS protections could be bypassed (i.e. sending telecommands to the OnBoard Computer) if I would manage to find an SPI pointing to memory space returning a Clear Mode SA. To perform the exploitation, two questions had to be answered: What are the conditions in the parser to trigger a Clear Mode SA and what are the conditions for the payload data unit (PDU) to be valid after SDLS parsing (because if I could bypass the security checks but the OBC would always reject the telecommand as invalid, the exploitation would not be so useful).
Conditions for Triggering a Clear Mode SA
The CryptoLib library implements Clear Mode (also referred to as SA_PLAINTEXT) and is triggered when the SA structure attributes encryption service type (est) and authentication service type (ast) are both equal to zero as shown in the snippet below extracted from the source code.
int32_t Crypto_TC_Get_SA_Service_Type(uint8_t* sa_service_type, SecurityAssociation_t* sa_ptr)
{
int32_t status = CRYPTO_LIB_SUCCESS;
if ((sa_ptr->est == 0) && (sa_ptr->ast == 0))
{ *sa_service_type = SA_PLAINTEXT; }
else if ((sa_ptr->est == 0) && (sa_ptr->ast == 1))
{ *sa_service_type = SA_AUTHENTICATION;}
else if ((sa_ptr->est == 1) && (sa_ptr->ast == 0))
{ *sa_service_type = SA_ENCRYPTION; }
else if ((sa_ptr->est == 1) && (sa_ptr->ast == 1))
{ *sa_service_type = SA_AUTHENTICATED_ENCRYPTION;}
else
{[...]
}
return status;
}
For the SA to be usable, it also has to pass sanity checks, which test the consistency of the configuration (e.g. ensuring the SDLS header IV length is less or equal to the IV length). Therefore, if we provide an SPI which can read memory where est and ast fields are zeros (2 bytes) and all other attributes pass the consistency test, the parsed frame will be using a Clear Mode SA.
Conditions for the payload data unit (PDU) to be valid after SDLS parsing
While checking all the SA structure attributes that determine the PDU (mainly field such as the secondary header iv length shivf_len, the secondary header length shsnf_len, the secondary pad length shplf_len and the secondary trailer mac length stmacf_len), I draw the conclusion that the best is for all of them to be equal to zero. Luckily for me, an SA with all these attributes equal to zero is a valid SA, i.e. passing the sanity checks.
Therefore, I used SPACE-SAT to generate frames with the SPI field being fuzzed while using a wrapper around cryptolib. In the context of fuzzing, I only had to wait for cryptolib to crash to capture the vulnerability being exploited but this time, I needed to know when the processing was successful. As my frame generator was set to not perform any cryptographic operation, the only way for the processing to be successful (i.e not crashing and error code == CRYPTO_LIB_SUCCESS) was to trigger a clear mode SA. A custom wrapper was developed to return the processing status: CRYPTO_LIB_SUCCESS, other cryptolib error codes, or seg fault.
After a few attempts, an SA was found (with a value of 8327) not in the range [0,NUM_SA] (Figure 3). As we can see, the return code is 0 (which means CRYPTO_LIB_SUCCESS); and all the SA attributes are zero (passing sanity checks). Hence, we successfully managed to bypass the SDLS protection!
The attack may not be deterministic in the sense that the location of the arbitrary read data that satisfies the SDLS bypass conditions is not always the same between different executions of the program. Moreover, this data may change during an operation, meaning the previously identified program memory may no longer trigger a valid clear mode SA. A more advanced analysis of the program memory could make this attack more deterministic. However, since I found a more effective exploitation, I did not spend further time on this attack.
A straightforward way to bypass SDLS
While analyzing the output of our successful bypass, I realized that I had identified a specific SA state where nearly all the structure attributes are set to zero (including est and ast). Therefore an SA passing the sanity checks and returning a clear mode SA. This behavior is the result of the sa_init() function. The function loops over all SA attributes and sets them to zero, except for three specific attributes. To understand the implications of this, let’s examine the SA memory management in three stages:
- SA_CREATED: The array containing the SAs is statically created, based on the NUM_SA variable.
- SA_INITALISED: The sa_init() function sets all attributes to zero.
- SA_CONFIGURED: The sa_configure() function then overwrites the SA with the provided configuration, as defined in the default configuration .
If the sa_configure() function does not overwrite the SA, the SA remains in its initialized state. In the default configuration, 64 SAs are initialized, but only 17 are configured. As a result, 43 SAs remain initialized but unconfigured, and these SAs are valid clear mode SA, as shown previously. Furthermore, there is no check of the security association state which is set to SA_NONE by default.This results in a vulnerability known as Improper control of dynamically-managed code resources.
With SPACE-SAT, I generated a frame with a TC header 002C00C000, SPI equal to 002C (SA 44 only initialized) and a payload 414243444546. I slighly modified the CryptoLib process security program to display the return code and data payload after parsing. As shown on Figure 4, the SA 44 is parsed as a TC Clear SA. The return code is 0 (i.e. CRYPTO_LIB_SUCCESS) and the TC PDU is our payload. With this, I successfully bypassed the SDLS protection of NASA CryptoLib !
Hijacking a spacecraft using SDLS Extended Procedures
According to the standard, dedicated channels with specific SPIs should be used to send EP commands to the spacecraft (specifically SPI 1 and 65535). CryptoLib, however, does not implement this according to the standard. To detect an SDLS-EP PDU, CryptoLib looks for either a specific VCID or a specific APID in the Space Packet Protocol. If one of these conditions is met, the PDU is parsed as an SDLS-EP PDU. Consequently, the previously identified vulnerabilities can be exploited to send SDLS-EP commands. CryptoLib is not implemented it according to the standard. To detect SDLS-EP PDU, CryptoLib is either looking for a specific VCID or a specific APID in the Space Packet Protocol. If one of two conditions match, the PDU is parsed as a SDLS-EP PDU. Therefore, the previsouly identified vulnerabilties can be used to send SDLS-EP commands. Being able to send EP commands is a massive power. We can imagine a scenario where we manage to erase all existing Security Associations (SAs) and upload our own, taking exclusive control of the spacecraft and denying access to the spacecraft operator. To execute this scenario, the following SDLS-EP commands would be required:
- sa_stop() to stop operational SA
- sa_expire() to unkey the SA
- sa_delete() to delete existing SA
- Crypto_Key_OTAR() to upload our key
- sa_create() to create our SA
- sa_rekey() to link the SA with our key
- sa_start() to set the SA to the operational state
All of these commands are implemented by CryptoLib. However, there is one limitation: the OTAR procedure adds an extra layer of security on top of the channel security. A master key, dedicated to this SDLS-EP command, is used to encrypt and authenticate the OTAR PDU. Therefore, to upload our key, we need to know one master key.
The OTAR procedure PDU is shown in Figure 4. The operator uploads an Encrypted Key ID and an Encrypted Key, both of which are encrypted and integrity-protected with a MAC. The Master Key ID (indicating the key used) and the Initialization Vector (IV) are cryptographic parameters that the spacecraft uses to verify authenticity and decrypt the PDU. For this cryptographic operation, no Security Associations are used (which also means there is no ARSN and no tracking of IV reuse). As a result, we cannot use our new SA bypass vulnerability directly; however, we can still apply the same underlying idea. We need to identify a Master Key ID whose value is known to us.
Key memory management is similar to SA memory management. A static array is used to store a structure composed of the key value, key length, and its state. The memory is initialized to all zeros, and the configuration is then applied, overwriting the initial configuration. Compared to the SA parser, the key parser is not vulnerable to out-of-bounds read attacks because a check is performed when retrieving the key. However, like the SA parser, the state of the key is not verified before use, so initialized keys are considered valid keys. In this context, this means that a all-zero key can be used. The only condition to meet is that the Master Key ID must be below 128, which can be easily fulfilled.
With SPACE-SAT, i generated a frame using SPI 44 to bypass the security channel and the VCID 4 to inform the spacecraft of a SDLS-EP command. Within the payload, an OTAR command with my own key (key id 129). I use a key initialised but not configured (i.e. Master key ID 64). The key ID and key value are encrypted using a 256bits key with value zero and 96bits of IV with value zero. As you can see on the Figure 5, the OTAR procedure worked, the return code is 0 (i.e. CRYPTO_LIB_SUCCESS).
For the other procedures, no hacking is needed, only to respect the data format. A new feature introduced in version 1.3.1 allowing to save and load the sa array between instances was used to witness the change of state. The following Figures show an example for the SA 1, fully updated with our new key.
The attacker then repeats the same procedure for the other 63 SAs and the operator is denied from communicating with the spacecraft (until it reboots since the SA/keys are stored in volatile memory).
We have demonstrated that all the necessary features to hijack the spacecraft have been implemented, making the attack feasible. Similar to the previous vulnerability, we can classify this one as Improper control of dynamically-managed code resources.
Decrypting the spacecraft operator telecommands without the key
Despite having exclusive control over the satellite, several key details remain unknown, such as the protocols used at the upper layer (e.g. SPP/PUS) and their configuration (e.g. how to trigger a trajectory modification). One way to gather more information is by sniffing legitimate traffic coming from the MCS. If the traffic is unencrypted, we can reverse-engineer the protocols and their configurations. However, if the traffic is encrypted, we would first need to decrypt the frames, but since we don’t know the key, and no EP commands can return it, this presents a challenge. Nevertheless, we can decrypt an encrypted payload without knowing the key, when AES GCM is used, if we manage to trigger IV reuse. When two messages use the same IV, their relationship is M1 xor E1 = M2 xor E2 where Mx is the clear message and Ex the corresponding encrypted message.
Thus, If 3 out the 4 variables are known, the fourth one can be recovered. For example: M2 = M1 xor E1 xor E2
The Key Verification procedure allows the verification of a set of active keys. This gives confirmation to the spacecraft operator that the keys are not corrupted or modified and are fully operational. To verify the key, the operator sends a challenge (random number) to the spacecraft with the key_id to test. Then, the spacecraft performs authenticated encryption on the challenge and return, through a reply pdu, the challenge encrypted with the IV used.
One important concept about this procedure (and the OTAR procedure) is that they don’t use keys through Security Association. Therefore, all the features provided by the SA are not performed, including the ARSN check and IV management. The implementer has to choose another way to manage this. As mentioned in the sdls-ep green book, « prevention of Key/IV collisions is implementation specific ». In the case of CryptoLib, they chose to use the IV of the TC frame that sent the key verification command and add 1 (.i.e TC IV+1) to encrypt the challenge. As we have the capability to send TC frames with any IV and send a key verification procedure, triggering IV Reuse on the key used by the operator to send telecommands is possible. This setup is called a keystream oracle, allowing us to recover the pseudo-random stream used to encrypt the operator’s telecommmands for a specific IV.
To simulate a legitimate frame from the operator, I generate, using SPACE-SAT, a frame encrypted and authenticated with AES-GCM, employing key_id 0 and a payload easily recognizable as 000102030405060708090A0B0C0D0E0F, with IV=1, as shown in Figure 10. The returned encrypted payload is CEOBB48BD837463A1B373F553E00D523. The objective is to recover the plaintext payload of this frame. Currently, we have 1 variable out of 4 (E1).
As the attacker, I generate a key verification command embedded in a TC frame with IV=0. We now know 2 variables out of 4 (E1, M2). This SDLS-EP command is sent to the spacecraft. Figure 11 shows the processing output of our challenge (normally, we would receive this reply from the TM channel). The frame data prior to encryption represents our challenge, while the frame data after encryption is the encrypted challenge (E2).
We now have 3 variables in hand, allowing us to recover the fourth one (M1). An XOR operation is sufficient to recover the plaintext message, as shown in Figure 12.
We successfully recover the initial payload ! Nevertheless, this attack is limited due to the fixed size of the challenge (16 bytes). We cannot fully decrypt a TC frame with a PDU greater than 16 bytes, but we can still learn key information. With 16 bytes, we could determine which protocols and configurations are used (e.g., the APID of the SPP) and even identify the application layer command header in the case of PUS (service and sub-service). In addition, the key verification procedure function is hardcoded to only verify key 0, making it non-functional for other keys as of today. it’s important to note that while the implementation is not fully vulnerable right now, it could have been tomorrow.
Security in Verification & Validation strategy
CryptoLib wiki page provides more information on their Verification & Validation strategy in 6 steps:
- Compatibility Testing,
- Unit Testing,
- Validation Testing,
- System Testing,
- Regression Testing, and
- Static Code Analysis.
Despite a well-defined and structured V&V (Verification and Validation) strategy, the vulnerabilities i described here were not found. I believe that an out of box testing is missing, i.e. a check that it does not do what the implementation is not expected to do. For instance, adding a fuzzer in the strategy could have detected the out-of-bounds vulnerability, and in general any input that would lead to a crash. That’s what I did, and I believe VisionSpace security team did the same based on their findings. Nevertheless, even if this was implemented, the new vulnerabilities would not have been found. Others methods/tools such as taint analysis, symbolic execution, completing Unit Tests with negative tests or using SPACE-SAT in the strategy could have helped detecting the vulnerabilities. The NIST provides some guidelines which includes software security verifications strategy and tools.
Responsible Disclosure, Mitigation & Patching
I disclosed the vulnerabilities responsably to the CryptoLib developpers by also proposing mitigations. This blog post was made public only after receiving their confirmation that I was free to publish
The table below summarizes the vulnerabilities presented, along with the proposed mitigations and their implementation, including references to the corresponding pull requests.
Vulnerability Name | CVE ID | CWE ID | Proposed Mitigation | Mitigation Implemented | Pull Request (PR) |
---|---|---|---|---|---|
SDLS Bypass | XXXXX | Improper control of dynamically-managed code resources | (1) An initialised SA should differ from a valid clear mode SA. (2) The SA existence and its state (e.g. OPERATIONAL) should be checked before use. (3) GCVID should be mapped to SAs (Principal of defense in depth) | 1. Check that SA is in operational state before use | PR286 PR306 |
Spacecraft Hijacking | XXXXX | Improper control of dynamically-managed code resources | (1) Define specific SPIs for SDLS-EP commands as per the standard (Principal of defense in depth) (2) Check the key state before use | (1) Define specific SAs (0 and NUM_SA-1) for SDLS-EP commands (2) Check key state before use (3) Check OTAR crypto function returned status | PR358 PR359 PR360 |
keystream Oracle | NA | Improper control of dynamically-managed code resources | Allocating a pool of IVs to the MCS and Spacecraft for this purpose. | 1. create a new set of build flags to enable / disable the extended procedures. More protections are going to be needed before flight | PR365 |
The out-of-bounds read vulnerability is already tackled in this PR269 as it was disclosed by VisionSpace.
Conclusion
This article demonstrated a way to exploit the out-of-bounds read vulnerability of NASA CryptoLib, resulting in bypassing the SDLS implementation, but also helped to identify a new vulnerability, Improper control of dynamically-managed code resources, leading to the same result. In addition, We also showed that an attacker could take exclusive control of a spacecraft leveraging the lack of state verification. Furthermore, we demonstrated how the key verifcation procedure can be used as a keystream oracle. These findings highlight the complexities of SDLS implementation and aim to raise awareness within the space community.
Acknowlegments
I would like to thank NASA for making this library open source, it is highly beneficial for anyone working with space communication protocols. I think I would not have written this article without the motivation from Antonios Atlasis. I would like to thank Antonios and Yohann Roiron for the review.
Glossary
AOS - Advanced Orbiting System
CCSDS - Committee for Space Data Systems
ECSS - European Cooperation for Space Standardisation
ESTEC - European Space Research and Technology Centre
OBC - OnBoard Computer
MCS - Mission Control System
PDU - Packet Data Unit
PUS – Packet Utilization Service
SA - Security Association
SDLS - Space Data Link Security
SPACE-SAT - Space Protocol Analysis, CCSDS & ECSS Security Assessment Toolset
SPI - Security Parameter Index
TC - Telecommand
TM - Telemetry
V&V - Verification & Validation