Skip to content

Commit 474a12c

Browse files
authored
Add NULL pointer validation to ML-KEM EVP encapsulate/decapsulate (#3132)
Add GUARD_PTR checks for ctx and ctx->data, and explicitNULL checks for length pointers and ciphertext buffer in pkey_kem_encapsulate and pkey_kem_decapsulate. This matches the defensive pattern already used in pkey_kem_encapsulate_deterministic and pkey_kem_keygen_deterministic in the same file. Functions now return ERR_R_PASSED_NULL_PARAMETER instead of crashing on NULL pointer arguments. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.
1 parent 70e4b2f commit 474a12c

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

crypto/fipsmodule/evp/p_kem.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ static int pkey_kem_encapsulate(EVP_PKEY_CTX *ctx,
194194
size_t *ciphertext_len,
195195
uint8_t *shared_secret,
196196
size_t *shared_secret_len) {
197+
GUARD_PTR(ctx);
197198
KEM_PKEY_CTX *dctx = ctx->data;
199+
GUARD_PTR(dctx);
198200
const KEM *kem = dctx->kem;
199201
if (kem == NULL) {
200202
if (ctx->pkey == NULL) {
@@ -204,6 +206,12 @@ static int pkey_kem_encapsulate(EVP_PKEY_CTX *ctx,
204206
kem = KEM_KEY_get0_kem(ctx->pkey->pkey.kem_key);
205207
}
206208

209+
// Check that length pointers can be written to.
210+
if (ciphertext_len == NULL || shared_secret_len == NULL) {
211+
OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER);
212+
return 0;
213+
}
214+
207215
// Caller is getting parameter values.
208216
if (ciphertext == NULL && shared_secret == NULL) {
209217
*ciphertext_len = kem->ciphertext_len;
@@ -257,7 +265,9 @@ static int pkey_kem_decapsulate(EVP_PKEY_CTX *ctx,
257265
size_t *shared_secret_len,
258266
const uint8_t *ciphertext,
259267
size_t ciphertext_len) {
268+
GUARD_PTR(ctx);
260269
KEM_PKEY_CTX *dctx = ctx->data;
270+
GUARD_PTR(dctx);
261271
const KEM *kem = dctx->kem;
262272
if (kem == NULL) {
263273
if (ctx->pkey == NULL) {
@@ -267,12 +277,24 @@ static int pkey_kem_decapsulate(EVP_PKEY_CTX *ctx,
267277
kem = KEM_KEY_get0_kem(ctx->pkey->pkey.kem_key);
268278
}
269279

280+
// Check that the length pointer can be written to.
281+
if (shared_secret_len == NULL) {
282+
OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER);
283+
return 0;
284+
}
285+
270286
// Caller is getting parameter values.
271287
if (shared_secret == NULL) {
272288
*shared_secret_len = kem->shared_secret_len;
273289
return 1;
274290
}
275291

292+
// The ciphertext buffer must be non-NULL for actual decapsulation.
293+
if (ciphertext == NULL) {
294+
OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER);
295+
return 0;
296+
}
297+
276298
// The input and output buffers need to be large enough.
277299
if (ciphertext_len != kem->ciphertext_len ||
278300
*shared_secret_len < kem->shared_secret_len) {

0 commit comments

Comments
 (0)