liboqs
liboqs copied to clipboard
Absence of explicit deletion from memory of intermediate values
As of version 0.13.0 of liboqs, we found that there is no explicit deletion of intermediate sensitive data in memory for at least the following mechanisms:
- KEM:
- Classic McEliece
- HQC
- NTRU Prime
- Signature:
- CROSS
- Falcon
- ML-DSA
- SPHINCS+
Furthermore, the liboqs implementation of the SHA-3 family does not contain a secure deletion of the internal state. As a consequence, a copy of sensitive values might still be present in memory in the heap when liboqs is compiled to use this implementation of the SHA-3 family. For example, the release of the internal state for SHAKE256 is:
static void SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) {
OQS_MEM_aligned_free(state->ctx);
}
And the function OQS_MEM_aligned_free() is a wrapper around a simple free().
Thanks for reporting this. We'd have different priorities for fixing this in the different algorithms. Here are some comments on that:
- SHA3: High priority to fix, since this is used by many PQ algorithms and the code lives within the OQS code base.
- ML-DSA: We plan to switch from the PQ-Crystals ML-DSA implementation to the PQ Code Package mldsa-native implementation in a couple of months once mldsa-native is ready.
- SPHINCS+: We plan to remove this in a few months when we add SLH-DSA.
- Falcon: Eventually NIST should release the FN-DSA spec and we'd want to update the code to that, at which point in time we'd want to have the behaviour you've mentioned fixed. Unclear what implementation would be the basis of FN-DSA in liboqs going forward.
- CROSS: Still an experimental algorithm in the NIST PQC signatures competition, so lower priority. Implementation coming from upstream so we'd want them to make the change there or we'd have to patch it in, depending on how extensive the changes are.
- HQC: Eventually NIST should release the HQC spec and we'd want to update the code to that, at which point in time we'd want to have the behaviour you've mentioned fixed. Unclear what implementation would be the basis of HQC in liboqs going forward.
- NTRU Prime: Currently no plans to remove / substantially change this algorithm, so should be fixed either in liboqs or in upstream. How extensive are the changes?
- Classic McEliece: Currently no plans to remove / substantially change this algorithm, so should be fixed either in liboqs or in upstream. How extensive are the changes?
Thank you for your response.
We are glad to know that the ML-DSA will migrate to the PQ Code Package such as ML-KEM.
The changes for NTRU Prime and Classic McEliece would require to identify which functions allocate and manipulate sensitive data that are not used outside.
For example, random polynomial generation in NTRU Prime generates random data, then it is copied to the output buffer, but the values are not cleared from the stack.
Since there are many implementations for various security levels, it might be a little bit extensive.
If you are interested in helping with any of these, we'd be grateful to receive your assistance.
Are explicit_bzero and memset_s the preferred methods in C code to zeroize memory? I'm happy to take a crack at some pieces of this - but wanted to get a sense of what the requirements are first.
IE in this context one should probably rewrite OQS_MEM_aligned_free to include a call to memset_s, correct? That way the memory is zeroized before it is handed back to the system allocator to dole out.
static void SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) {
OQS_MEM_aligned_free(state->ctx);
}
We have the OQS_MEM_cleanse function for this purpose, which will select one of memset_s and explicit_bzero if available.
We have the
OQS_MEM_cleansefunction for this purpose, which will select one ofmemset_sandexplicit_bzeroif available.
So it would just be a matter of placing those before the OQS_MEM_aligned_free within SHA3's routines for example?
We have the
OQS_MEM_cleansefunction for this purpose, which will select one ofmemset_sandexplicit_bzeroif available.So it would just be a matter of placing those before the OQS_MEM_aligned_free within
SHA3's routines for example?
Yes, I believe so. If this is a common pattern, we could also create a secure aligned free function which combines the two.
Sorted out (part of?) the SHA3 implementation in https://github.com/open-quantum-safe/liboqs/pull/2171/commits/3491e9be0d6cf879592d9aee7fc10ba021865b89