core: derive key: fix out-of-bounds write in SM2-KEP derivation - #7942
Conversation
|
Please look into the CI error(s). |
8954dd7 to
df29562
Compare
|
I've force-pushed a corrected version of this commit. The first version also converted the length with That was wrong: in the SM2-KEP path The GENERIC_SECRET KAT in The actual issue is only a missing bound: The commit now leaves I also corrected the commit authorship so the DCO check passes. |
9e15484 to
9d2a13d
Compare
|
Edit: wait with that R-B. I have a few comments. |
jenswikl
left a comment
There was a problem hiding this comment.
Reviewed-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>
| struct ecc_public_key peer_key = { }; | ||
| struct sm2_kep_parms kep_parms = { | ||
| .out = (uint8_t *)(sk + 1), | ||
| .out_len = so->info.maxObjectSize, |
There was a problem hiding this comment.
It seems that .out_len still has the wrong value. However, I think we can take that in a separate PR to fix the bits-vs-bytes confusion, since that will involve xtest case 4014. Would you mind fixing that too (later), or shall I?
There was a problem hiding this comment.
Thanks for the review — glad the bounds check (the actual OOB-write guard) is good to merge as-is.
I'd be happy to take the bits-vs-bytes cleanup as a separate follow-up.
To makesure I get it right this time (the earlier /8 attempt broke regression_4014 precisely because I only touched the derive side):
my understanding is that so->info.maxObjectSize for the SM2-KEP GENERIC_SECRET output should be in bits per the GP convention, so out_len should be maxObjectSize / 8 bytes and regression_4014 needs to allocate the output object with the bit size (8 * sizeof(gmt_003_part5_b2_shared_secret)) rather than the byte size, so the KAT still matches.
Does that match your intent? If so, I'll prepare the optee_os + optee_test change together in a new PR.
(And if you'd rather take it yourself, that's completely fine. just let me know.)
There was a problem hiding this comment.
That's how I understand it too.
|
Please apply my R-B, and I'll merge this. |
In syscall_cryp_derive_key(), the TEE_ALG_SM2_KEP branch passes so->info.maxObjectSize as the number of bytes sm2_kdf() writes into the derived key's secret buffer, without checking it against sk->alloc_size. For a TEE_TYPE_GENERIC_SECRET object sk->alloc_size is fixed at 4096 / 8 = 512 bytes, while maxObjectSize may be requested up to 4096. Requesting an output larger than 512 makes sm2_kdf() write past the allocation -- up to a ~3.5 KiB heap overflow. The sibling key-derivation branches (HKDF, Concat KDF, PBKDF2) already reject a derived length larger than sk->alloc_size; the SM2-KEP branch was missed. Add the same check. Fixes: 9e47f7e ("core: derive key: check provided out key size") Signed-off-by: Gyeongsik Song <secretpack97@gmail.com> Reviewed-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>
9d2a13d to
be46b60
Compare
Done, applied your Reviewed-by, thanks! |
What
In
syscall_cryp_derive_key()theTEE_ALG_SM2_KEPbranch passesso->info.maxObjectSizeas the number of bytessm2_kdf()writes into the derived key's secret buffer, but never bounds it againstsk->alloc_size.For a
TEE_TYPE_GENERIC_SECRETobjectsk->alloc_sizeis fixed at4096 / 8 = 512bytes, whilemaxObjectSizemay be requested up to4096.A caller that allocates the output object with a size in
(512, 4096]and runs an SM2-KEPTEE_DeriveKey()makessm2_kdf()write past the allocation up to a ~3.5 KiB heap overflow.The sibling key-derivation branches (HKDF, Concat KDF, PBKDF2) already reject a derived length larger than
sk->alloc_size; the SM2-KEP branch was missed.Fix
Add the
out_len > sk->alloc_sizecheck to the SM2-KEP branch, matching the other derivation branches.out_len(= `maxd, so the GENERIC_SECRET known-answer test (regression_4014, 16-byte output) is unaffected.Testing
CFG_CRYPTO_SM2_KEP=y)xtest regression_4014(SM2-KEP KAT) passes (16-byte output, < 512).